package de.geraldschenke.tictactoe;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import de.geraldschenke.tictactoe.common.GameEvent;
import de.geraldschenke.tictactoe.common.GameProperties;
import de.geraldschenke.tictactoe.common.RemotePlayer;
import de.geraldschenke.tictactoe.common.ai.NormalAI;
import de.geraldschenke.tictactoe.common.ai.RandomAI;
import de.geraldschenke.tictactoe.common.ai.StupidAI;
import de.geraldschenke.tictactoe.server.GameThread;

/**
 * The main Activity for the TicTacToe game. This starts the game thread,
 * registers players and initializes the view...
 * 
 */
public class TicTacToeActivity extends Activity {
	private TicTacToeView mTTTview;
	private GameThread mGameThread;

	// static handler class with weakReference to prevent memory leaks
	static class GameEventHandler extends Handler {
		WeakReference<TicTacToeView> refTicTacToeView;

		GameEventHandler(TicTacToeView tttView) {
			refTicTacToeView = new WeakReference<TicTacToeView>(tttView);
		}

		@Override
		public void handleMessage(Message message) {
			if (!(message.obj instanceof GameEvent)) {
				return;
			}
			GameEvent gameEvent = (GameEvent) message.obj;
			TicTacToeView tttView = refTicTacToeView.get();
			switch (message.what) {
			case 0: // GameEvent.Type.UPDATE_BOARD
				tttView.mBoard = gameEvent.board;
				if (gameEvent.gameOver) {
					tttView.announceWinner(gameEvent.winner);
				}
			}
			if (tttView != null){
				tttView.invalidate();
				Log.d("GameEventHandler","Got event. updated board and invalidated view");
			}else{
				Log.w("GameEventHandler","Got event. But View is null!");
			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mGameThread = new GameThread();
		mGameThread.start();

		// Get the message from the intent
		Intent intent = getIntent();
		int player1type = intent.getIntExtra(MainActivity.PLAYER1, 0);
		int player2type = intent.getIntExtra(MainActivity.PLAYER2, 0);

		final GameProperties gameProperties = new GameProperties();
		mTTTview = new TicTacToeView(this, gameProperties, mGameThread);

		// create new player with Handler inside
		Handler gameEventHandler = new GameEventHandler(mTTTview);

		// before calling the gamethread be sure it runs and was initialized!
		long time = System.currentTimeMillis();
		while (true) {
			if (mGameThread.isInitialized()) {
				break;
			}
			if (System.currentTimeMillis() - time > 50) {
				throw new RuntimeException("Unable to start Game. Sorry!");
			}
			try {
				wait(1);
			} catch (InterruptedException e) {
				// i dont care!
			}
		}

		final RemotePlayer player1;
		if (player1type == 0){
			player1 = new HumanPlayer(gameEventHandler);
			mTTTview.addHumanPlayer(player1);
			Log.d("tttActivity", "player1 is human!");
		}else if (player1type == 1){
			player1 = new StupidAI(mGameThread);
			Log.d("tttActivity", "player1 is stupid AI!");
		}else if (player1type == 2){
			player1 = new RandomAI(mGameThread);
			Log.d("tttActivity", "player1 is random AI!");
		}else{
			player1 = new NormalAI(mGameThread);
			Log.d("tttActivity", "player1 is normal AI!");
		}
		final RemotePlayer player2;
		if (player2type == 0){
			player2 = new HumanPlayer(gameEventHandler);
			mTTTview.addHumanPlayer(player2);
			Log.d("tttActivity", "player2 is human!");
		}else if (player2type == 1){
			player2 = new StupidAI(mGameThread);
			Log.d("tttActivity", "player2 is stupid AI!");
		}else if (player2type == 2){
			player2 = new RandomAI(mGameThread);
			Log.d("tttActivity", "player2 is random AI!");
		}else{
			player2 = new NormalAI(mGameThread);
			Log.d("tttActivity", "player2 is normal AI!");
		}
		
		int player1Id = mGameThread.registerPlayer(player1);
		player1.setPlayerId(player1Id);
		int player2Id = mGameThread.registerPlayer(player2);
		player2.setPlayerId(player2Id);
		
		Log.d("tttActivity", "player ids: player1="+player1Id+" player2="+player2Id);
		
		if (player1type != 0 && player2type != 0){
			//bots playing!
			mGameThread.registerObserver(new HumanPlayer(gameEventHandler));
		}

		mGameThread.startGame(gameProperties);

		setContentView(mTTTview);
	}

	@Override
	public void onBackPressed() {
		Log.d("TicTacToeActivity", "onBackPressed Called");
		mGameThread.requestStop();
		super.onBackPressed();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mGameThread.requestStop();
	}
}
